package com.ha.security.config;


/*  @Configuration注解描述的类是sping中的配置类 启动时会优先加载这个

 *
 **/

import com.ha.security.config.handler.DefaultAccessDeniedExceptionHandler;
import com.ha.security.config.handler.DefaultAuthenticationEntryPoint;
import com.ha.security.config.handler.RedirectAuthenticationSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
 * 由@Configuration注解描述的类为spring中的配置类,配置类会在spring
 * 工程启动时优先加载,在配置类中通常会对第三方资源进行初始配置.
 */
//用于描述权限控制类,底层在启动时,进行访问权限的初始化
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /*
    配置我们的页面登录的设置
     继承接口WebSecurityConfigurerAdapte 实现他的接口方法 configure 方法 就可以
     修改我们前端登陆的页面配置
      */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
       //1.关闭跨域攻击
        http.csrf().disable();
        //2.配置用户url的登录页面
        http.formLogin()
                .loginPage("/login.html")//允许放行的资源(我们的登录资源)
                .loginProcessingUrl("/login")
               // .usernameParameter("username")//配置我们的登录的页面的绑定信息的字段
                //.passwordParameter("password")//前端的页面的字段必须和这里的相对应
                //.successForwardUrl("/hello.html")//这个方法是其他的页面的路由方向
                //.defaultSuccessUrl("/index.html")//这个方法是默认的方法.登录成功后的页面
               .successHandler(new RedirectAuthenticationSuccessHandler("/index.html"))
                .failureUrl("/login.html?error");//默认失败的页面操作

      http.logout().logoutUrl("/logout").logoutSuccessUrl("/login.html?logout");

        //设置需要认证与拒绝访问的异常处理器
        http.exceptionHandling()
                .authenticationEntryPoint(//没有认证时执行DefaultAuthenticationEntryPoint对象
                        new DefaultAuthenticationEntryPoint())
                .accessDeniedHandler(//没有授权时执行DefaultAccessDeniedExceptionHandler对象
                        new DefaultAccessDeniedExceptionHandler());


      //放行登录的url,(不需要认证就可以登录)authorize(请求资源)
        http.authorizeRequests()
                .antMatchers("/login.html","/images/**")//需要放行的资源
                .permitAll()//允许直接访问
                .anyRequest().authenticated();//除了以上资源.其他的必须认证权限才能访问



    }
    /**
     * 定义SpringSecurity密码加密对象
     * @Bean 注解通常会在@Configuration注解描述的类中描述方法,
     * 用于告诉spring框架这个方法的返回值会交给spring管理,并spring
     * 管理的这个对象起个默认的名字,这个名字与方法名相同,当然也可以通过
     * @Bean注解起名字
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){

        return new BCryptPasswordEncoder();

    }
}